package com.retrofit.server.processor;

import com.google.auto.service.AutoService;
import com.okhttp.annotations.ApiGenerateService;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Filer;
import javax.annotation.processing.Messager;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.Processor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;
import javax.tools.Diagnostic.Kind;

/**
 * 编译生成Retrofit Service 接口实现类
 */
//java版本支持
@SupportedSourceVersion(SourceVersion.RELEASE_8)
//标注注解处理器支持的注解类型，只处理BindRetrofitService注解
@SupportedAnnotationTypes("com.okhttp.annotations.BindRetrofitService")
//自动生成javax.annotation.processing.processor
@AutoService(Processor.class)
public class RetrofitServerProcessor extends AbstractProcessor {

  private Types typeUtils;
  private Elements elementUtils;
  private Filer filer;
  private Messager messager;


  @Override
  public synchronized void init(ProcessingEnvironment processingEnvironment) {
    super.init(processingEnvironment);
    Print.log("init");
    typeUtils=processingEnvironment.getTypeUtils();
    elementUtils = processingEnv.getElementUtils();
    filer = processingEnv.getFiler();
    messager = processingEnvironment.getMessager();
    Map<String, String> map = processingEnv.getOptions();
    Set<String> keys = map.keySet();
    for (String key : keys) {
      if ("isPrint".equals(key)) {
        try{
          Print.isPrint =Boolean.parseBoolean(map.get(key));
        }catch (Exception e){
          Print.isPrint=false;
        }
      }
      Print.log(">>>>>>>>> " + key + " = " + map.get(key));
    }
  }

  @Override
  public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
    //只拦截BindRetrofitSerivce 注解
    Print.log("processor (annotations)：" + annotations.size());
    if(annotations.size()<1){
      return false;
    }
    Print.log("process annotations "+annotations.toString());
    try {
      // 扫描 BingRetrofitService 注解的类
      Set<? extends Element> elements = roundEnv.getElementsAnnotatedWith(ApiGenerateService.class);
      for (Element annotatedElement : elements) {
        //检查是否是BindRetrofitService 注解的接口（这里不能注解类）
        if (annotatedElement.getKind() != ElementKind.INTERFACE) {
          throw new ProcessorException(annotatedElement, " @%s 只能注解 Retrofit 接口服务, @%s 不是接口类",
              ApiGenerateService.class.getSimpleName(),annotatedElement.toString());
        }
        //
        TypeElement typeElement = (TypeElement) annotatedElement;
        AnnotationClass annotationClass=new AnnotationClass(elementUtils,typeUtils,typeElement);
        //
        new JavaFileGenerate().generateClass(annotationClass).generateJavaFile(processingEnv);

      }
    } catch (ProcessorException processorException) {
      error(processorException.getElement(), processorException.getMessage());
    }
    return false;
  }


  @Override
  public Set<String> getSupportedAnnotationTypes() {
    Print.log("getSupportedAnnotationTypes");
    return Collections.singleton(ApiGenerateService.class.getCanonicalName());
  }


  @Override
  public SourceVersion getSupportedSourceVersion() {
    return SourceVersion.latestSupported();
  }
  

  /**
   * 打印错误并退出
   * @param element
   * @param msg
   */
  private void error(Element element,String msg){
    messager.printMessage(Kind.ERROR,msg);
  }


}
